package com.zxx.casserver.modules.user.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.zxx.cascommon.base.exception.ParamsException;
import com.zxx.cascommon.base.result.Result;
import com.zxx.cascommon.base.result.ResultUtils;
import com.zxx.cascommon.base.utils.GenerateServiceIdUtils;
import com.zxx.casserver.modules.oplog.aop.OpLogAnnotation;
import com.zxx.casserver.modules.user.entity.UserDO;
import com.zxx.casserver.modules.user.entity.UserRelationVO;
import com.zxx.casserver.modules.user.entity.UserVO;
import com.zxx.casserver.modules.user.service.IUserService;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;

/**
 * 用户信息管理-控制层
 *
 * @author zhoukai
 * @date 2020/6/24 16:58
 */
@RestController
@RequestMapping("/user")
public class UserController {

    private final IUserService userService;

    private final DefaultKaptcha captchaProducer;

    public UserController(IUserService userService, DefaultKaptcha defaultKaptcha) {
        this.userService = userService;
        this.captchaProducer = defaultKaptcha;
    }

    @PostMapping("/getVerifyCode")
    public void getVerifyCode(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        byte[] captchaOutputStream = null;
        ByteArrayOutputStream imgOutputStream = new ByteArrayOutputStream();
        try {
            //生成随机生成的ID字符串并保存到session中，用来查询缓存里面实际的值
            String verifyCode = captchaProducer.createText();
            GenerateServiceIdUtils generateId = new GenerateServiceIdUtils(62,1);

            //判断是否已经有请求ID，有请求ID之后，取已有的ID进行处理，防止多次请求导致redis内存溢出
            String requestId = httpServletRequest.getSession().getAttribute("verifyCode")+"";
            if(ObjectUtils.isEmpty(requestId)){
                requestId = generateId.nextId()+"";
            }
            userService.saveVerifyCode(requestId+"",verifyCode);
            httpServletRequest.getSession().setAttribute("verifyCode", requestId);
            BufferedImage challenge = captchaProducer.createImage(verifyCode);
            ImageIO.write(challenge, "jpg", imgOutputStream);
        } catch (IllegalArgumentException e) {
            throw new ParamsException("生成验证码失败，请稍后再试");
        }
        captchaOutputStream = imgOutputStream.toByteArray();
        httpServletResponse.setHeader("Cache-Control", "no-store");
        httpServletResponse.setHeader("Pragma", "no-cache");
        httpServletResponse.setDateHeader("Expires", 0);
        httpServletResponse.setContentType("image/jpeg");
        ServletOutputStream responseOutputStream = httpServletResponse.getOutputStream();
        responseOutputStream.write(captchaOutputStream);
        responseOutputStream.flush();
        responseOutputStream.close();
    }



    @PostMapping("/get")
    public Result getUser(@RequestBody UserVO userVO) {
        if (ObjectUtils.isEmpty(userVO.getUid())) {
            throw new ParamsException();
        }
        if (ObjectUtils.isEmpty(userVO.getAppId())) {
            throw new ParamsException();
        }
        UserVO userBO = userService.getUser(userVO);
        if (ObjectUtils.isEmpty(userBO)) {
            return ResultUtils.fail(new JSONObject());
        }
        return ResultUtils.success(userBO);
    }

    @OpLogAnnotation(modules = "用户",
            action = "登陆", msg = "用户登陆")
    @PostMapping("/login")
    public Result login(@RequestBody UserVO userVO, HttpSession session) {
        if (ObjectUtils.isEmpty(userVO.getAccount())) {
            throw new ParamsException();
        }
        if (ObjectUtils.isEmpty(userVO.getAppId())) {
            throw new ParamsException();
        }
        if (ObjectUtils.isEmpty(userVO.getPassword())) {
            throw new ParamsException();
        }
        if (ObjectUtils.isEmpty(userVO.getVerifyCode())) {
            throw new ParamsException();
        }
        String requestId = session.getAttribute("verifyCode") + "";
        if (ObjectUtils.isEmpty(requestId)) {
            throw new ParamsException("验证码请求ID为空，无法登陆");
        }
        userVO.setRequestId(requestId);
        UserVO userBO = userService.login(userVO);
        if (ObjectUtils.isEmpty(userBO)) {
            return ResultUtils.fail("用户登陆失败");
        }
        return ResultUtils.success(userBO);
    }

    @OpLogAnnotation(modules = "用户",
            action = "登出", msg = "用户登出")
    @PostMapping("/loginOut")
    public Result loginOut(@RequestBody UserVO userVO) {
        if (ObjectUtils.isEmpty(userVO.getToken())) {
            throw new ParamsException();
        }
        Boolean loginOut = userService.loginOut(userVO);
        if (ObjectUtils.isEmpty(loginOut) || !loginOut) {
            return ResultUtils.fail(new JSONObject());
        }
        return ResultUtils.success(true);
    }


    @PostMapping("/checkLogin")
    public Result checkLogin(@RequestBody UserVO userVO) {
        if (ObjectUtils.isEmpty(userVO.getToken())) {
            throw new ParamsException();
        }
        UserVO userBO = userService.checkLogin(userVO);
        if (ObjectUtils.isEmpty(userBO)) {
            return ResultUtils.tokenExpired("token失效，请重新登陆");
        }
        return ResultUtils.success(userBO);
    }


    @PostMapping("/list")
    public Result listUser(@RequestBody UserVO userVO) {
        if (ObjectUtils.isEmpty(userVO.getToken())) {
            throw new ParamsException();
        }
        IPage<UserDO> userPage = userService.listUser(userVO);
        if (ObjectUtils.isEmpty(userPage)) {
            return ResultUtils.fail(new JSONObject());
        }
        return ResultUtils.success(userService.dispose(userPage));
    }

    @OpLogAnnotation(modules = "用户",
            action = "保存", msg = "用户保存")
    @PostMapping("/save")
    public Result saveUser(@RequestBody UserVO userVO) {
        if (ObjectUtils.isEmpty(userVO.getPlatformId())) {
            throw new ParamsException();
        }
        if (ObjectUtils.isEmpty(userVO.getAppId())) {
            throw new ParamsException();
        }
        if (ObjectUtils.isEmpty(userVO.getName())) {
            throw new ParamsException();
        }
        if (ObjectUtils.isEmpty(userVO.getAccount())) {
            throw new ParamsException();
        }
        if (ObjectUtils.isEmpty(userVO.getPassword())) {
            throw new ParamsException();
        }
        UserDO userDO = userService.saveUser(userVO);
        if (ObjectUtils.isEmpty(userDO)) {
            return ResultUtils.fail(new JSONObject());
        }
        return ResultUtils.success(userDO);
    }

    @OpLogAnnotation(modules = "用户",
            action = "重制密码", msg = "用户重制密码")
    @PostMapping("/resetPassword")
    public Result resetPassword(@RequestBody UserVO userVO) {
        if (ObjectUtils.isEmpty(userVO.getUid())) {
            throw new ParamsException();
        }
        if (ObjectUtils.isEmpty(userVO.getPassword())) {
            throw new ParamsException();
        }
        Boolean reset = userService.resetPassword(userVO);
        if (ObjectUtils.isEmpty(reset) || !reset) {
            return ResultUtils.fail(false);
        }
        return ResultUtils.success(true);
    }


    @OpLogAnnotation(modules = "用户",
            action = "更新", msg = "用户更新")
    @PostMapping("/update")
    public Result updateUser(@RequestBody UserVO userVO) {
        if (ObjectUtils.isEmpty(userVO.getUid())) {
            throw new ParamsException();
        }
        UserDO userDO = userService.updateUser(userVO);
        if (ObjectUtils.isEmpty(userDO)) {
            return ResultUtils.fail(new JSONObject());
        }
        return ResultUtils.success(userDO);
    }


    @OpLogAnnotation(modules = "用户",
            action = "删除", msg = "用户删除")
    @PostMapping("/remove")
    public Result removeUser(@RequestBody UserVO userVO) {
        if (ObjectUtils.isEmpty(userVO.getUid())) {
            throw new ParamsException();
        }
        UserDO userDO = userService.removeUser(userVO);
        if (ObjectUtils.isEmpty(userDO)) {
            return ResultUtils.fail(new JSONObject());
        }
        return ResultUtils.success(userDO);
    }


    @OpLogAnnotation(modules = "用户关系",
            action = "新增", msg = "用户关联关系新增")
    @PostMapping("/relation/save")
    public Result saveRelation(@RequestBody UserRelationVO userRelationVO) {
        if (ObjectUtils.isEmpty(userRelationVO.getUid())) {
            throw new ParamsException();
        }
        if (ObjectUtils.isEmpty(userRelationVO.getType())) {
            throw new ParamsException();
        }
        if (ObjectUtils.isEmpty(userRelationVO.getRelationList())) {
            throw new ParamsException();
        }
        Boolean isSave = userService.saveRelation(userRelationVO);
        if (ObjectUtils.isEmpty(isSave) || isSave) {
            return ResultUtils.fail(false);
        }
        return ResultUtils.success(true);
    }

}
